#ifndef __myApplication_h__
#define __myApplication_h__

#include "OgreApplication.h"
#include "OgreAL.h"
//#include <Xinput.h>

#define PLAYER_1_CAM "player1Camera"
#define PLAYER_2_CAM "player2Camera"
#define MOVE_SPEED 1000
#define DEAD_ZONE 0.2
#define SCALE_VALUE 30

#define LEFT_THUMB_UD 0
#define LEFT_THUMB_LR_AXIS 1
#define LEFT_THUMB_UD_AXIS 0
#define RIGHT_THUMB_UD 2
#define SHOULDER_ANALOGUE 4

#define XBOX_BUTTON_A 0
#define XBOX_BUTTON_B 1
#define XBOX_BUTTON_X 2
#define XBOX_BUTTON_Y 3
#define XBOX_BUTTON_BACK 6
#define XBOX_BUTTON_START 7

#define LEFT_VIEWPORT 1
#define RIGHT_VIEWPORT 0


void setupViewport(RenderWindow *win, SceneManager *curr)
{
	win->removeAllViewports();

   // Create one viewport, entire window
   Viewport* vp = 0;
   Camera* cam = curr->getCamera(PLAYER_1_CAM);
   //vp = win->addViewport(cam, 0,0,0,0.5,1);
   vp = win->addViewport(cam);
   vp->setBackgroundColour(ColourValue(0,0,0));

   // Alter the camera aspect ratio to match the viewport
   cam->setAspectRatio(Real(vp->getActualWidth()) / Real(vp->getActualHeight()));
}

//passes in 2 scenes but only using 1 atm with 2 cameras, didn't want to take 2nd out in case of later use
void dualViewport(RenderWindow *win, SceneManager *primary, SceneManager *secondary)
{
   win->removeAllViewports();

   Viewport *vp = 0;
   Viewport *vp2 = 0;
   Camera *cam = primary->getCamera(PLAYER_1_CAM);
   vp = win->addViewport(cam, 0, 0, 0, 0.5, 1);
   vp->setBackgroundColour(ColourValue(0,0,0));
   cam->setAspectRatio(Real(vp->getActualWidth()) / Real(vp->getActualHeight()));

   cam = primary->getCamera(PLAYER_2_CAM);
   vp2 = win->addViewport(cam, 1, 0.5, 0, 0.5, 1);
   vp2->setBackgroundColour(ColourValue(0,0,0));
   cam->setAspectRatio(Real(vp2->getActualWidth()) / Real(vp2->getActualHeight()));
}

class myFrameListener : public ExampleFrameListener
{
protected:         
    Real mMove;     
	Real mRotate;
    SceneManager *mPrimary, *mSecondary;   
    SceneNode *mCamNode;  
	Camera *gameCam, *gameCam2;
	Entity *player, *playerTwo;
	bool mDual, mContinue;
	RaySceneQuery *mRaySceneQuery;
	OgreOde::World *World;
	OgreOde::StepHandler *Stepper;

	OgreOde_Prefab::Vehicle *goKart;
	OgreOde_Prefab::Vehicle *goKart2;
	OgreOde_Prefab::Vehicle	*Obstacle1;
	OgreOde_Prefab::Vehicle	*Obstacle2;
	OgreOde_Prefab::Vehicle	*Obstacle3;
	OgreOde_Prefab::Vehicle	*Obstacle4;
	OgreOde_Prefab::Vehicle	*Obstacle5;

	Ogre::OverlayManager* overlay, *intOverlay;
	Ogre::OverlayContainer* speedBarCont, *timerCont, *l_speedBarCont, *r_speedBarCont, *posBarCont, *intCont;
	Ogre::OverlayElement* speedBarElem, *blueHelmetElem,*redHelmetElem, *l_speedBarElem, *r_speedBarElem, *intSelector_elem;

	Ogre::TextAreaOverlayElement* mTextArea; 
	Ogre::TextAreaOverlayElement* mTextArea1; 
	Ogre::TextAreaOverlayElement* mTextArea2; 
	Ogre::TextAreaOverlayElement* mTextArea3;

	Ogre::TextAreaOverlayElement* r_mTextArea; 
	Ogre::TextAreaOverlayElement* r_mTextArea1; 
	Ogre::TextAreaOverlayElement* r_mTextArea2; 
	Ogre::TextAreaOverlayElement* r_mTextArea3;

	Ogre::Real LeftAxisValue_pad2;
	Ogre::Real RightAxisValue_pad2;
	Ogre::Real LeftAxisValue;
	Ogre::Real RightAxisValue;

	Ogre::Timer *Timer;
	Ogre::Timer *r_Timer;

	bool Waypoint1,Waypoint2,Waypoint3,Waypoint4,firstlap, startGame;
	bool r_Waypoint1,r_Waypoint2,r_Waypoint3,r_Waypoint4,r_firstlap;

	double tMinutes, r_tMinutes;
	double tSeconds, r_tSeconds;
	double tMilliSeconds, r_tMilliSeconds;
	int Laps, r_Laps;
	int player1Count, player2Count;
	Ogre::Real wayTimerPlayer1, wayTimerPlayer2;

	//std::ofstream lapData;
	std::ifstream lapData;
	Ogre::String  data;
	Ogre::Real Steer;
	Ogre::Real engineBrakePos;
	Ogre::Real engineThrottlePos;


	std::ostringstream Lap[3];
	std::ostringstream r_Lap[3];
	
	OgreAL::SoundManager* sManager;
	OgreAL::Sound* sound, *startGameSound, *cursorMove, *introMusic, *inGameMusic1;
	static void swap(SceneManager *&first, SceneManager *&second)
    {
        SceneManager *tmp = first;
        first = second;
        second = tmp;
    }
public:

	int needleAngle;
	
	myFrameListener(SceneManager *primary,SceneManager *secondary, RenderWindow* win, OgreOde::World* mWorld, OgreOde::StepHandler* mStepper, OgreOde_Prefab::Vehicle *Vehicle,OgreOde_Prefab::Vehicle *Vehicle2,OgreOde_Prefab::Vehicle *Vehicle3,OgreOde_Prefab::Vehicle *Vehicle4,OgreOde_Prefab::Vehicle *Vehicle5,OgreOde_Prefab::Vehicle *Vehicle6,OgreOde_Prefab::Vehicle *Vehicle7, Ogre::OverlayManager* olay ,OgreAL::SoundManager* sman, bool go, Ogre::OverlayManager* iolay)
         : ExampleFrameListener(win, primary->getCamera(PLAYER_1_CAM),true, true,false),
		 mPrimary(primary), mSecondary(secondary), mDual(false), mContinue(true), mMove(MOVE_SPEED), mRotate(0.1), mCamNode(primary->getCamera(PLAYER_1_CAM)->getParentSceneNode()),
		 mRaySceneQuery(primary->createRayQuery(Ray())), overlay(olay), sManager(sman), intOverlay(iolay)
	{
		startGame = go;

		startGame = false;
		World = mWorld;
		Stepper = mStepper;
		mRotate = 0.0;

		goKart = Vehicle;
		goKart2 = Vehicle2;
		Obstacle1 = Vehicle3;
		Obstacle2 = Vehicle4;
		Obstacle3 = Vehicle5;
		Obstacle4 = Vehicle6;
		Obstacle4 = Vehicle7;

		mTextArea = static_cast<Ogre::TextAreaOverlayElement*>(overlay->getOverlayElement("currentLap"));
		mTextArea1 = static_cast<Ogre::TextAreaOverlayElement*>(overlay->getOverlayElement("Lap1"));
		mTextArea2 = static_cast<Ogre::TextAreaOverlayElement*>(overlay->getOverlayElement("Lap2"));
		mTextArea3 = static_cast<Ogre::TextAreaOverlayElement*>(overlay->getOverlayElement("Lap3"));

		r_mTextArea = static_cast<Ogre::TextAreaOverlayElement*>(overlay->getOverlayElement("r_currentLap"));
		r_mTextArea1 = static_cast<Ogre::TextAreaOverlayElement*>(overlay->getOverlayElement("r_Lap1"));
		r_mTextArea2 = static_cast<Ogre::TextAreaOverlayElement*>(overlay->getOverlayElement("r_Lap2"));
		r_mTextArea3 = static_cast<Ogre::TextAreaOverlayElement*>(overlay->getOverlayElement("r_Lap3"));

		speedBarCont = static_cast<Ogre::OverlayContainer*>(overlay->getOverlayElement("SpeedBarPanel"));
		l_speedBarCont = static_cast<Ogre::OverlayContainer*>(overlay->getOverlayElement("l_SpeedBarPanel"));
		r_speedBarCont = static_cast<Ogre::OverlayContainer*>(overlay->getOverlayElement("r_SpeedBarPanel"));
		timerCont = static_cast<Ogre::OverlayContainer*>(overlay->getOverlayElement("TimerPanel"));
		posBarCont = static_cast<Ogre::OverlayContainer*>(overlay->getOverlayElement("positionBarPanel"));
		speedBarElem = speedBarCont->getChild("goKartMedia/speedBarOverlay");
		l_speedBarElem = l_speedBarCont->getChild("goKartMedia/leftScreenspeedBarOverlay");
		r_speedBarElem = r_speedBarCont->getChild("goKartMedia/rightScreenspeedBarOverlay");
		blueHelmetElem = posBarCont->getChild("goKartMedia/helmet_blue");
		redHelmetElem = posBarCont->getChild("goKartMedia/helmet_red");

		sound = sManager->getSound("sound1");
		startGameSound = sManager->getSound("startGameSound");
		cursorMove = sManager->getSound("cursorMove");
		introMusic = sManager->getSound("introMusic");
		inGameMusic1 = sManager->getSound("inGameMusic1");

		intCont = static_cast<Ogre::OverlayContainer*>(intOverlay->getOverlayElement("titlePanel"));
		intSelector_elem = intCont->getChild("goKartMedia/selector");
	

		Timer = new Ogre::Timer();
		Waypoint1 = false;
		Waypoint2 = false;
		Waypoint3 = false;
		Waypoint4 = true;
		firstlap = true;
		
		r_Timer = new Ogre::Timer();
		r_Waypoint1 = false;
		r_Waypoint2 = false;
		r_Waypoint3 = false;
		r_Waypoint4 = true;
		r_firstlap = true;

		gameCam = mPrimary->getCamera(PLAYER_1_CAM);
		gameCam2= mPrimary->getCamera(PLAYER_2_CAM);
		Laps = 0;
		r_Laps = 0;
		player1Count = 0;
		player2Count = 0;
		wayTimerPlayer1 = 0;
		wayTimerPlayer2 = 0;

		lapData.open("Example.txt");
		//lapData.open("Example.txt");
		data = "";
		Steer = 0;
	    engineBrakePos = 0;
	    engineThrottlePos = 0;
		

	}

	bool frameStarted(const FrameEvent& evt)
	{
		if( mJoy ) mJoy->capture();
		if( mJoy2 ) mJoy2->capture();
		mKeyboard->capture();

		if( mJoy ) LeftAxisValue = mJoy->getJoyStickState().mAxes[LEFT_THUMB_UD_AXIS].abs;
		if( mJoy2 ) LeftAxisValue_pad2 = mJoy2->getJoyStickState().mAxes[LEFT_THUMB_UD_AXIS].abs;
		if( mJoy ) LeftAxisValue = (LeftAxisValue / 32768);
		if( mJoy2 ) LeftAxisValue_pad2 = (LeftAxisValue_pad2 / 32768);

		
		if( mJoy ){
			if(LeftAxisValue < DEAD_ZONE && LeftAxisValue > -DEAD_ZONE)
				LeftAxisValue = 0;
		}

		if( mJoy2 ){
			if(LeftAxisValue_pad2 < DEAD_ZONE && LeftAxisValue_pad2 > -DEAD_ZONE)
				LeftAxisValue_pad2 = 0;
		}

		if(mKeyboard->isKeyDown(OIS::KC_ESCAPE))
			return false;

		if(!startGame)
		{
			introMusic->setGain(0.1);
			introMusic->play();
			if(mJoy && mTimeUntilNextToggle <= 0){
				if(/*mJoy->getJoyStickState().mPOV[0].direction == 16*/LeftAxisValue > DEAD_ZONE){
					intSelector_elem->setTop(intSelector_elem->getTop()+50);
					if(cursorMove->isPlaying())
						cursorMove->stop();
					cursorMove->play();
					mTimeUntilNextToggle = 1.5;
				}
				if(intSelector_elem->getTop() > 50)
					intSelector_elem->setTop(0);
			}
			if(mJoy && mTimeUntilNextToggle <= 0){
				if(/*mJoy->getJoyStickState().mPOV[0].direction == 1*/LeftAxisValue < -DEAD_ZONE){
					intSelector_elem->setTop(intSelector_elem->getTop()-50);
					if(cursorMove->isPlaying())
						cursorMove->stop();
					cursorMove->play();
					mTimeUntilNextToggle = 1.5;
				}
				if(intSelector_elem->getTop() < 0)
					intSelector_elem->setTop(50);
			}

			if(mJoy){
				if(mJoy->getJoyStickState().buttonDown(XBOX_BUTTON_A)){
					if(intSelector_elem->getTop() == 0){
						intOverlay->getOverlayElement("titlePanel")->hide();
						startGameSound->play();
						introMusic->stop();
						startGame = !startGame;
					}
						
					if(intSelector_elem->getTop() == 50){
						startGameSound->play();
						return false;
					}
				}

			}

			if(mKeyboard->isKeyDown(OIS::KC_RETURN)){
				intOverlay->getOverlayElement("titlePanel")->hide();
					startGame = !startGame;
			}
			mTimeUntilNextToggle -= 0.1;
		}

		if(startGame)
		{

		//if(!inGameMusic1->isPlaying())
		//	inGameMusic1->play();

		std::ostringstream gg;
		std::ostringstream ss;
		std::ostringstream timer;
		std::ostringstream r_timer;


	/*	std::ostringstream ss;
		ss << data;
		mDebugText = "" + ss.str();*/


		////////////////////Calculate Timers/////////////////////////////
		tMinutes  = (Timer->getMilliseconds()/60000);
		 tSeconds = (Timer->getMilliseconds() % 60000) / 1000;
		 tMilliSeconds = (Timer->getMilliseconds()%1000);

		 if(tMinutes != 0)
		 {
			 timer << tMinutes << ":" << tSeconds << ":" << tMilliSeconds;
			
		 }
		 else
		 {
			 timer << tSeconds << ":" << tMilliSeconds;		
		 }

		 r_tMinutes  = (r_Timer->getMilliseconds()/60000);
		 r_tSeconds = (r_Timer->getMilliseconds() % 60000) / 1000;
		 r_tMilliSeconds = (r_Timer->getMilliseconds()%1000);

		 if(r_tMinutes != 0)
		 {
			 r_timer << r_tMinutes << ":" << r_tSeconds << ":" << r_tMilliSeconds;
			
		 }
		 else
		 {
			 r_timer << r_tSeconds << ":" << r_tMilliSeconds;
			
		 }
		 //////////////////////////////////////////////////////////////
		/////////////////////Output Timers///////////////////////////
		 mTextArea->setCaption("" +timer.str());
		 mTextArea1->setCaption("" + Lap[0].str());
		 mTextArea2->setCaption("" + Lap[1].str());
		 mTextArea3->setCaption("" + Lap[2].str());

		 r_mTextArea->setCaption("" +r_timer.str());
		 r_mTextArea1->setCaption("" + r_Lap[0].str());
		 r_mTextArea2->setCaption("" + r_Lap[1].str());
		 r_mTextArea3->setCaption("" + r_Lap[2].str());
		 ///////////////////////////////////////////////////////////
		 
		 if(speedBarElem->isVisible()){
			 speedBarElem->setWidth(goKart->getVelocity()*7.8);
			 if(speedBarElem->getWidth() > 351 )
				 speedBarElem->setWidth(355);
		 }

		 if(l_speedBarElem->isVisible()){
			 l_speedBarElem->setWidth(goKart->getVelocity()*7.8);
			 if(l_speedBarElem->getWidth() > 351 )
				 l_speedBarElem->setWidth(355);
		 }

		 if(r_speedBarElem->isVisible()){
			 r_speedBarElem->setWidth(goKart2->getVelocity()*7.8);
			 if(r_speedBarElem->getWidth() > 351 )
				 r_speedBarElem->setWidth(355);
		 }


		 if(!sound->isPlaying())
			 sound->play();
		sound->setPitch((goKart->getVelocity()/50)+0.5);
		sound->setGain((goKart->getVelocity()/200)+0.1);

		Ogre::Real time = (evt.timeSinceLastFrame)/3;



		if( mJoy ) LeftAxisValue = mJoy->getJoyStickState().mAxes[LEFT_THUMB_LR_AXIS].abs;
		if( mJoy ) RightAxisValue = mJoy->getJoyStickState().mAxes[SHOULDER_ANALOGUE].abs;



		if( mJoy2 ) LeftAxisValue_pad2 = mJoy2->getJoyStickState().mAxes[LEFT_THUMB_LR_AXIS].abs;
		if( mJoy2 ) RightAxisValue_pad2 = mJoy2->getJoyStickState().mAxes[SHOULDER_ANALOGUE].abs;


		if( mJoy ) LeftAxisValue = (LeftAxisValue / 32768);
		if( mJoy ) RightAxisValue = (RightAxisValue / 32768);

		if( mJoy2 ) LeftAxisValue_pad2 = (LeftAxisValue_pad2 / 32768);
		if( mJoy2 ) RightAxisValue_pad2 = (RightAxisValue_pad2 / 32768);
		
		if( mJoy ){
			if(LeftAxisValue < DEAD_ZONE && LeftAxisValue > -DEAD_ZONE)
				LeftAxisValue = 0;
		}

		if( mJoy2 ){
			if(LeftAxisValue_pad2 < DEAD_ZONE && LeftAxisValue_pad2 > -DEAD_ZONE)
				LeftAxisValue_pad2 = 0;
		}

		if( mJoy ){
			if(mJoy->getJoyStickState().buttonDown(XBOX_BUTTON_B))
				goKart->getEngine()->setRevLimit(250);
			else if(goKart->getVelocity() <= 30)
				goKart->getEngine()->setRevLimit(180);
		}
		goKart2->getEngine()->setRevLimit(180);

		if( mJoy2 ){
			if(mJoy2->getJoyStickState().buttonDown(XBOX_BUTTON_B))
				goKart2->getEngine()->setRevLimit(250);
			else if(goKart2->getVelocity() <= 30)
				goKart2->getEngine()->setRevLimit(180);
		}
			

		if( mJoy )	goKart->setInputs(LeftAxisValue, RightAxisValue);
		else
			goKart->setInputs(mKeyboard->isKeyDown(OIS::KC_J), mKeyboard->isKeyDown(OIS::KC_L), mKeyboard->isKeyDown(OIS::KC_I), mKeyboard->isKeyDown(OIS::KC_K));

		if( mJoy2 ) goKart2->setInputs(LeftAxisValue_pad2, RightAxisValue_pad2);
		else
			goKart2->setInputs(mKeyboard->isKeyDown(OIS::KC_A),mKeyboard->isKeyDown(OIS::KC_D),mKeyboard->isKeyDown(OIS::KC_W), mKeyboard->isKeyDown(OIS::KC_S));

		
	//	lapData << LeftAxisValue*evt.timeSinceLastFrame << "\n" << RightAxisValue*evt.timeSinceLastFrame << "\n";


		std::getline(lapData, data);
		Steer = Ogre::StringConverter::parseReal(data);

		std::getline(lapData, data);
		engineThrottlePos = Ogre::StringConverter::parseReal(data);

		//goKart->setInputs(Steer/evt.timeSinceLastFrame, engineThrottlePos/evt.timeSinceLastFrame);
		//goKart2->setInputs(Steer,engineThrottlePos);



		
		
		goKart->update(time);
		goKart2->update(time);
		Obstacle1->update(time);
		Obstacle2->update(time);
		Obstacle3->update(time);
		Obstacle4->update(time);
		Obstacle4->update(time);

		if( mJoy )
		{
			if(mJoy->getJoyStickState().buttonDown(XBOX_BUTTON_Y))
			{
				int i;
				Real rpm = FLT_MIN;
				for (i = 0; i<4; i++)
				{
					rpm = std::max(rpm,goKart->getWheel(i)->getRPM());

				}

				Real power = goKart->getEngine()->getPowerAtRPM(rpm);
				Real desired_rpm = goKart->getEngine()->getDesiredRPM();
				Real brake = goKart->getEngine()->getBrakeForce();

				for (i = 0; i<4; i++)
				{
					goKart->getWheel(i)->update(power,-desired_rpm,brake);
				}
			}
		}

		if( mJoy2 )
		{
			if(mJoy2->getJoyStickState().buttonDown(XBOX_BUTTON_Y))
			{
				int i;
				Real rpm = FLT_MIN;
				for (i = 0; i<4; i++)
				{
					rpm = std::max(rpm,goKart2->getWheel(i)->getRPM());

				}

				Real power = goKart2->getEngine()->getPowerAtRPM(rpm);
				Real desired_rpm = goKart2->getEngine()->getDesiredRPM();
				Real brake = goKart2->getEngine()->getBrakeForce(); 

				for (i = 0; i<4; i++)
				{
					goKart2->getWheel(i)->update(power,-desired_rpm,brake);
				}
			}
		}




		
		if(mKeyboard->isKeyDown(OIS::KC_ESCAPE))
			return false;

		if(mKeyboard->isKeyDown(OIS::KC_V) && mTimeUntilNextToggle <= 0)
		{
			mDual = !mDual;

			if(mDual){
				dualViewport(mWindow, mPrimary, mSecondary);
				mTimeUntilNextToggle = 4.0;
			}
			else{
				setupViewport(mWindow, mPrimary);
				mTimeUntilNextToggle = 4.0;

			}

			
		}

		if(mTimeUntilNextToggle > 0)
			mTimeUntilNextToggle -= 0.1;

		if(goKart->getPosition().y > 105)
		{
			 World->setGravity(Vector3(0,-18.80665,0));
		}
		else
		{
			World->setGravity(Vector3(0,-9.80665,0));
		}
		if(goKart2->getPosition().y > 105)
		{
			 World->setGravity(Vector3(0,-18.80665,0));
		}
		else
		{
			World->setGravity(Vector3(0,-9.80665,0));
		}

		if (Stepper->step(time))
       {
           World->synchronise();
       }

	   	if(goKart->getPosition().x >238 && goKart->getPosition().x <265  && goKart->getPosition().z >132 && goKart->getPosition().z < 138 && Waypoint4 == true)
		{
			
			if(firstlap == false && Laps <= 2)
			{
				Lap[Laps] << tMinutes << ":" << tSeconds << ":" << tMilliSeconds;
				wayTimerPlayer1 = Timer->getMilliseconds();
				Timer->reset();
				Laps++;

				player1Count++;
				
			}
			Waypoint1 = true;
		    Waypoint2 = false;
		    Waypoint3 = false;
		    Waypoint4 = false;
			firstlap = false;
		}
		if(goKart->getPosition().x >192 && goKart->getPosition().x < 226 && goKart->getPosition().z >333 && goKart->getPosition().z < 339 && Waypoint1 == true)
		{		
			Waypoint1 = false;
			Waypoint2 = true;
			player1Count++;
			wayTimerPlayer1 = Timer->getMilliseconds();

		}
		if(goKart->getPosition().x >18 && goKart->getPosition().x < 44 && goKart->getPosition().z >110 && goKart->getPosition().z < 125 && Waypoint2 == true)
		{
			Waypoint2 = false;
			Waypoint3 = true;
			player1Count++;
			wayTimerPlayer1 = Timer->getMilliseconds();
		}
		if(goKart->getPosition().x >160 && goKart->getPosition().x < 205 && goKart->getPosition().z >-125 && goKart->getPosition().z < -110 && Waypoint3 == true)
		{
			Waypoint3 = false;
			Waypoint4 = true;
			player1Count++;
			wayTimerPlayer1 = Timer->getMilliseconds();
		}
//PLAYER 2 WAY POINTS
		if(goKart2->getPosition().x >238 && goKart2->getPosition().x <265  && goKart2->getPosition().z >132 && goKart2->getPosition().z < 138 && r_Waypoint4 == true)
		{
			
			if(r_firstlap == false && r_Laps <= 2)
			{
				r_Lap[r_Laps] << r_tMinutes << ":" << r_tSeconds << ":" << r_tMilliSeconds;
				wayTimerPlayer2 = r_Timer->getMilliseconds();
				r_Timer->reset();
				r_Laps++;
				player2Count++;
			}
			r_Waypoint1 = true;
		    r_Waypoint2 = false;
		    r_Waypoint3 = false;
		    r_Waypoint4 = false;
			r_firstlap = false;
		}
		if(goKart2->getPosition().x >192 && goKart2->getPosition().x < 226 && goKart2->getPosition().z >333 && goKart2->getPosition().z < 339 && r_Waypoint1 == true)
		{
			r_Waypoint1 = false;
			r_Waypoint2 = true;
			player2Count++;
			wayTimerPlayer2 = r_Timer->getMilliseconds();
		}
		if(goKart2->getPosition().x >18 && goKart2->getPosition().x < 44 && goKart2->getPosition().z >110 && goKart2->getPosition().z < 125 && r_Waypoint2 == true)
		{
			r_Waypoint2 = false;
			r_Waypoint3 = true;
			player2Count++;
			wayTimerPlayer2 = r_Timer->getMilliseconds();
		}
		if(goKart2->getPosition().x >160 && goKart2->getPosition().x < 205 && goKart2->getPosition().z >-125 && goKart2->getPosition().z < -110 && r_Waypoint3 == true)
		{
			r_Waypoint3 = false;
			r_Waypoint4 = true;
			player2Count++;
			wayTimerPlayer2 = r_Timer->getMilliseconds();
		}

/////////////////////////////////////////////////////////////////////////////////////////////////////
//Calculate who is first and who is second
	if(player1Count != player2Count)
	{
		if(std::max(player1Count, player2Count) == player1Count)
		{
			//player1 = first
			blueHelmetElem->setTop(400);
			redHelmetElem->setTop(585);
		}
		if(std::max(player1Count, player2Count) == player2Count)
		{
			//player2 = first
			redHelmetElem->setTop(400);
			blueHelmetElem->setTop(585);
		}
	}
	else{
		//Both on same waypoint
		if(std::max(wayTimerPlayer1, wayTimerPlayer2) == wayTimerPlayer1)
		{
			//player1 = second
			redHelmetElem->setTop(400);
			blueHelmetElem->setTop(585);
		}
		if(std::max(wayTimerPlayer1, wayTimerPlayer2) == wayTimerPlayer2)
		{
			//player2 = second
			blueHelmetElem->setTop(400);
			redHelmetElem->setTop(585);
		}

	}

	if(redHelmetElem->getTop() == blueHelmetElem->getTop())
		redHelmetElem->setLeft(60);
	else
		redHelmetElem->setLeft(20);

/////////////////////////////////////////////////////////////////////
	if( mJoy ){
		if(mJoy->getJoyStickState().buttonDown(XBOX_BUTTON_START))
			{
				if(player1Count % 4 == 1)
				{
					goKart->getBody()->setOrientation(goKart->getSceneNode()->getInitialOrientation());
				
				///goKart->getBody()->setOrientation(goKart->getSceneNode()->getOrientation().getYaw());
					//goKart->getSceneNode()->yaw(Degree(180));
					goKart->setPosition(Vector3(213.54,100.606,276.125));
				}
				if(player1Count % 4 == 2)
				{
					goKart->getBody()->setOrientation(goKart->getSceneNode()->getInitialOrientation());
					goKart->setPosition(Vector3(-2.59,99.346,16));
				}
				if(player1Count % 4 == 3)
				{
					goKart->getBody()->setOrientation(goKart->getSceneNode()->getInitialOrientation());
					goKart->setPosition(Vector3(204,100.606,-163.776));
				}
				if(player1Count % 4 == 0)
				{
					goKart->getBody()->setOrientation(goKart->getSceneNode()->getInitialOrientation());
					goKart->setPosition(Vector3(253.015,99.36,154.195));
				}
		}
	}
	if( mJoy2 )
	{
		if(mJoy2->getJoyStickState().buttonDown(XBOX_BUTTON_START))
			{
				if(player2Count % 4 == 1)
				{
					goKart2->getBody()->setOrientation(goKart2->getSceneNode()->getInitialOrientation());
					
					goKart2->setPosition(Vector3(213.54,100.606,276.125));
				}
				if(player2Count % 4 == 2)
				{
					goKart2->getBody()->setOrientation(goKart2->getSceneNode()->getInitialOrientation());
					goKart2->setPosition(Vector3(-2.59,99.346,16));
				}
				if(player2Count % 4 == 3)
				{
					goKart2->getBody()->setOrientation(goKart2->getSceneNode()->getInitialOrientation());
					goKart2->setPosition(Vector3(204,100.606,-163.776));
				}
				if(player2Count % 4 == 0)
				{
					goKart2->getBody()->setOrientation(goKart2->getSceneNode()->getInitialOrientation());
					goKart2->setPosition(Vector3(253.015,99.36,154.195));
				}
		}
	}



		const Ogre::Real followFactor = 0.2; 
		const Ogre::Real camHeight = 2.0; 
		const Ogre::Real camDistance = 7.0; 
		const Ogre::Real camLookAhead = 8.0;
//CAMERA 1

		Quaternion q = goKart->getSceneNode()->getOrientation(); 
		Vector3 toCam = goKart->getSceneNode()->getPosition(); 

		toCam.y += camHeight; 
		toCam.z -= (camDistance * q.zAxis().z); 
		toCam.x -= (camDistance * q.zAxis().x); 
	      
		gameCam->move( (toCam - gameCam->getPosition()) * followFactor ); 
		gameCam->lookAt(goKart->getSceneNode()->getPosition());

//CAMERA 2
		Quaternion q2 = goKart2->getSceneNode()->getOrientation(); 
		Vector3 toCam2 = goKart2->getSceneNode()->getPosition(); 

		toCam2.y += camHeight; 
		toCam2.z -= (camDistance * q2.zAxis().z); 
		toCam2.x -= (camDistance * q2.zAxis().x); 
	      
		gameCam2->move( (toCam2 - gameCam2->getPosition()) * followFactor ); 
		gameCam2->lookAt(goKart2->getSceneNode()->getPosition());


		double shortestDist[6] = {1000000000,10000000000,10000000000,10000000000,10000000000,10000000000};
		double lightIndex[6] = {40,40,40,40,40,40};

		for(int z = 0; z<3; z++)
		{
			for(int i = 0; i< 23; i++)
			{
				 for(int j=0; j<3; j++)
				 {
					 if(goKart->getPosition().distance(mPrimary->getSceneNode("lampN"+Ogre::StringConverter::toString(i))->getPosition()) < shortestDist[j]
					 && i != lightIndex[0] && i != lightIndex[1] && i != lightIndex[2])
					 {
						 shortestDist[j] = goKart->getPosition().distance(mPrimary->getSceneNode("lampN"+Ogre::StringConverter::toString(i))->getPosition());
						 lightIndex[j] = i; 								 
					 }
				 }
			}
			
		
		}
	

		for(int z = 0; z< 3; z++)
		{
			for(int i = 0; i< 23; i++)
			{
				 for(int j=3; j< 6; j++)
				 {
					 if(goKart2->getPosition().distance(mPrimary->getSceneNode("lampN"+Ogre::StringConverter::toString(i))->getPosition()) < shortestDist[j]
					 && i != lightIndex[3] && i != lightIndex[4] && i != lightIndex[5])
					 {
						 shortestDist[j] = goKart2->getPosition().distance(mPrimary->getSceneNode("lampN"+Ogre::StringConverter::toString(i))->getPosition());
						 lightIndex[j] = i;
										 						 
					 }
				 }
		
			}
		}
		

		for(int i =0; i<23; i++)
		{
			int count = 0;
			for (int j=0; j<6; j++)
			{
				if(lightIndex[j] == i)
				{
				
						mPrimary->getLight("floodlight"+Ogre::StringConverter::toString(i))->setVisible(true);
					
				}
				else
				{
					count++;
						if(count == 6)
						mPrimary->getLight("floodlight"+Ogre::StringConverter::toString(i))->setVisible(false);
					
				}
			}

		}


		ss << player1Count;
		mDebugText = "" + ss.str();
		}//START GAME

		return true;

	}


};

class viewPortOverlayListener : public Ogre::RenderTargetListener 
{
public:
	Ogre::RenderWindow* vWindow;
	Ogre::OverlayManager* olayManager;
		
	viewPortOverlayListener(Ogre::RenderWindow* win, Ogre::OverlayManager* olay)
	{
		vWindow = win;
		olayManager = olay;
	}


	void preViewportUpdate( const Ogre::RenderTargetViewportEvent& evt);
	void postViewportUpdate( const Ogre::RenderTargetViewportEvent& evt);
};


class myApplication : public OgreApplication, public OgreOde::CollisionListener
{
public:
   myApplication(void);
   virtual ~myApplication();



protected:
   virtual void createScene();
   virtual void initTitleScreen();
   virtual bool frameStarted(const FrameEvent& evt);
   virtual void createSceneManager();
   virtual void createCamera();
   virtual void createViewports();
   virtual void initSpotLights(void);
   virtual void createSpotLights(int,Vector3,Vector3,Radian,Radian);
   virtual void initRamps();
   virtual void createRamps(int, Vector3, Degree);

   virtual void createFrameListener(void)
   {
	   mFrameListener= new myFrameListener(primarySceneMgr, introSceneMgr, mWindow, mWorld, mStepper, goKart,goKart2,Obstacle1,Obstacle2,Obstacle3,Obstacle4,Obstacle5 ,overlayMgr, soundManager, startGame, introOverlayMgr);
		mRoot->addFrameListener(mFrameListener);
   }

   virtual bool collision(OgreOde::Contact* Contact);



   Entity* playerPlane;
   Entity* playerTwoPlane;
   Entity* Track;
   SceneNode* playerNode;
   SceneNode* playerTwoNode;
   SceneNode* trackNode;
   SceneNode* primCamNode;
   SceneNode* secCamNode;
   SceneManager* primarySceneMgr;
   SceneManager* introSceneMgr;
   Camera* primSceneCam;
   Camera* secSceneCam;
   Camera* introSceneCam;
   caelum::CaelumSystem* mCaelumSystem;
   Ogre::OverlayManager* overlayMgr;
   Ogre::OverlayManager* introOverlayMgr;
   OgreAL::SoundManager* soundManager;
   OgreAL::Sound* sound, *music, *sound2, *startGameSound, *cursorMove, *introMusic, *inGameMusic1;
   viewPortOverlayListener* VPOL;
   Light* lightArr[23];
   SceneNode* lampNode[23];
   Entity*   lampEnt[23];
   Entity* rampEnt[6];
   SceneNode* rampNode[6];


  // caelum::SkyColourModel* mCaelumModel;



};





#endif // #ifndef __myApplication_h__